home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BCI NET
/
BCI NET Dec 94.iso
/
archives
/
programming
/
source
/
tsmorph30s.lha
/
TSM30s.lha
/
apack.asm
next >
Wrap
Assembly Source File
|
1994-02-09
|
8KB
|
254 lines
****************************************************************
*
* Copyright 1988 by CREATIVE FOCUS. This code is freely
* distributable as long as this notice is retained and no
* other conditions are imposed upon its redistribution.
*
*
* APACK.ASM --
*
* A fully compatible replacement for Electronic Arts' PACKER.C
* routine. Converts data according to the IFF ILBM cmpByteRun1
* compression protocol:
*
* control bytes:
*
* n = 0.. 127: followed by n+1 bytes of data;
* n = -1..-127: followed by byte to be repeated -n+1 times;
* n = -128: don't do no nada.
*
* calling format:
*
* long packrow(from, too, amt)
* char **from, /* pointer to source data pointer */
* **too; /* pointer to destination data pointer */
* long amt; /* number of bytes to compress */
*
* return(number of bytes written to destination);
*
* effects:
*
* *from = *from + amt, and *too = *too + return;
* return is "smart," that is, not greater than
* MaxPackedSize = amt + ((amt+127) >> 7).
*
* By commenting out CHECK (below) you disable checking for runs
* exceeding 128 bytes. That CHECK is not needed if you are sure
* the amt to be compressed is always 128 or less.
*
* !!! DISCLAIMER !!! You use this code entirely at your own
* risk. I don't warrantee its fitness for any purpose. I
* can't even guarantee the accuracy of anything I've said
* about it, though I've tried my damndest to get it right.
* I may, in fact, be completely out of my tiny little mind :-).
*
* That being said, I can be reached for questions, comments,
* or concerns at:
*
* Dr. Gerald Hull
* CREATIVE FOCUS
* 12 White Street
* Binghamton, N.Y. 13901
* (607) 648-4082
*
* bix: ghull
* PLink: DRJERRY
*
***************************************************************
* edited by mjp to compile with SAS/C 5.10
xdef _packrow
section code
*a0 equr a0 -> beginning of replicate run (if any)
*a1 equr a1 -> end+1 of input line
*a2 equr a2 -> beginning of literal run (if any)
*a3 equr a3 -> end+1 of lit and/or rep run (if any)
*a4 equr a4 -> end+1 of output line current pos
*a5 equr a6 frame pointer
*a7 equr a7 stack pointer
*d0 equr d0 return value
*d1 equr d1 check for maximum run = MAX
*d2 equr d2 amount
*d3 equr d3 character
*d2/d3/a2/a3/a4 reg d2/d3/a2/a3/a4
FRM equ 8 input line address
TOO equ 12 output line address
AMT equ 16 length of input line
MAX equ 128 maximum encodable output run
CHECK equ 1 turns on maximum row checking
_packrow
*************** CASE 0: GRAB PARAMS & INITIALIZE
CAS0
link a5,#0
movem.l d2/d3/a2/a3/a4,-(a7)
movea.l FRM(a5),a2
movea.l (a2),a2 a2 = *from
movea.l a2,a3 a3 = a2
movea.l a3,a1
adda.l AMT(a5),a1 a1 = a2 + amt
movea.l TOO(a5),a4
movea.l (a4),a4 a4 = *too
*************** CASE 1: LITERAL RUN
CAS1
movea.l a3,a0 adjust a0 (no replicates yet!)
move.b (a3)+,d3 grab character
cmpa.l a3,a1 if input is finished
beq.s CAS5 branch to case 5
ifd CHECK
move.l a3,d1
sub.l a2,d1
cmpi #MAX,d1 if run has reached MAX
beq.s CAS6 branch to case 6
endc
cmp.b (a3),d3 if next character != d3
bne.s CAS1 stay in case 1
* else fall into case 2
*************** CASE 2: AT LEAST 2 BYTE REPEAT
CAS2
move.b (a3)+,d3 grab character
cmpa.l a3,a1 if input is finished
beq.s CAS7 branch to case 7
ifd CHECK
move.l a3,d1
sub.l a2,d1
cmpi #MAX,d1 if run has reached MAX
beq.s CAS6 branch to case 6
endc
cmp.b (a3),d3 if next character != d3
bne.s CAS1 branch to case 1
* else fall into case 3
*************** CASE 3: REPLICATE RUN
CAS3
move.b (a3)+,d3 grab character
cmpa.l a3,a1 if input is finished
beq.s CAS7 branch to case 7
ifd CHECK
move.l a3,d1
sub.l a0,d1
cmpi #MAX,d1 if run has reached MAX
beq.s CAS4 branch to case 4
endc
cmp.b (a3),d3 if next character = d3
beq.s CAS3 stay in case 3
* else fall into case 4
*************** CASE 4: LIT AND/OR REP DUMP & CONTINUE
CAS4
move.l a0,d2
sub.l a2,d2 d2 = a0 - a2
* if no literal run
beq.s C41 branch to replicate run
subq #1,d2 d2 = d2 - 1
move.b d2,(a4)+ output literal control byte
C40 move.b (a2)+,(a4)+ output literal run
dbra d2,C40
C41 move.l a0,d2
sub.l a3,d2 d2 = a0 - a3 (negative result!)
addq #1,d2 d2 = d2 + 1
move.b d2,(a4)+ output replicate control byte
move.b d3,(a4)+ output repeated character
movea.l a3,a2 reset a2
bra.s CAS1 branch to case 1 (not done)
*************** CASE 5: LITERAL DUMP & QUIT
CAS5
move.l a3,d2
sub.l a2,d2 d2 = a3 - a2 (positive result > 0)
subq #1,d2 d2 = d2 - 1
move.b d2,(a4)+ output literal control byte
C50 move.b (a2)+,(a4)+ output literal run
dbra d2,C50
bra.s CAS8 branch to case 8 (done)
ifd CHECK
*************** CASE 6: LITERAL DUMP & CONTINUE
CAS6
move.l a3,d2
sub.l a2,d2 d2 = a3 - a2 (positive result > 0)
subq #1,d2 d2 = d2 - 1
move.b d2,(a4)+ output literal control byte
C60 move.b (a2)+,(a4)+ output literal run
dbra d2,C60
bra CAS1 branch to case 1 (not done)
endc
*************** CASE 7: LIT AND/OR REP DUMP & FINISH
CAS7
move.l a0,d2
sub.l a2,d2 d2 = a0 - a2 (positive result > 0)
* if no literal run
beq.s C71 branch to replicate run
subq #1,d2 d2 = d2 - 1
move.b d2,(a4)+ output literal control byte
C70 move.b (a2)+,(a4)+ output literal run
dbra d2,C70
C71 move.l a0,d2
sub.l a3,d2 d2 = a0 - a3 (negative result)
addq #1,d2 d2 = d2 + 1
move.b d2,(a4)+ output replicate control byte
move.b d3,(a4)+ output repeated character
* fall into case 8
*************** CASE 8: ADJUST PARAMS & RETURN VALUE
CAS8
movea.l FRM(a5),a0 a0 = **from
move.l a3,(a0) *from = *from + amt
movea.l TOO(a5),a0 a0 = **too
move.l a4,d0
sub.l (a0),d0 return = a4 - *too
move.l a4,(a0) *too = *too + return
movem.l (a7)+,d2/d3/a2/a3/a4
UNLK a5
rts
end